/*
 * XFCSet.java
 * 
 * Copyright (c) 2006 - 2007
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
package org.xfc.xdemos.swingset;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.prefs.Preferences;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.table.DefaultTableCellRenderer;

import org.xfc.XApp;
import org.xfc.XAppFrame;
import org.xfc.components.XActionLabel;
import org.xfc.components.XMinimizablePanel;
import org.xfc.components.XMultilineLabel;
import org.xfc.components.XSplitPane;
import org.xfc.components.XTabbedPane;
import org.xfc.components.XTabbedPaneListenerAdapter;
import org.xfc.components.XTabbedPaneTab;
import org.xfc.components.XThrobber;
import org.xfc.dialog.XAboutBox;
import org.xfc.dialog.XErrorDialog;
import org.xfc.dialog.XLoginDialog;
import org.xfc.dialog.XPreferenceDialog;
import org.xfc.dialog.XPreferenceTab;
import org.xfc.dialog.XProgressDialog;
import org.xfc.dialog.XSplashScreen;
import org.xfc.editor.XBindery;
import org.xfc.editor.XCompositeEditor;
import org.xfc.editor.XStringEditor;
import org.xfc.help.XHelpBrowser;
import org.xfc.model.XObject;
import org.xfc.print.XPrintUtilities;
import org.xfc.table.XRowHeaderRenderer;
import org.xfc.table.XTable;
import org.xfc.table.XTableColumn;
import org.xfc.util.XResources;
import org.xfc.util.XUtils;
import org.xfc.wizard.XDefaultWizardPage;
import org.xfc.wizard.XWizardListenerAdapter;
import org.xfc.wizard.XWizardDialog;

import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;

import com.jgoodies.forms.layout.FormLayout;

/**
 * 
 * 
 * @author Devon Carew
 */
public class XFCSwingSet
	extends XApp
{
	static Action ABOUT_ACTION;
	
	public static void main(String[] args)
		throws IOException
	{
		// Create the singleton instance of the application.
		XFCSwingSet app = new XFCSwingSet();
		
		XSplashScreen splashScreen = new XSplashScreen(app.getResources().getIcon("/org/xfc/xdemos/swingset/portland.jpg"));
		splashScreen.setText("XFC SwingSet");
		splashScreen.setForeground(Color.WHITE);
		splashScreen.show();
		
		// TODO: Remove. code overage test
		for (int i = 0; i < 25000; i++)
		{
			int x = i * 3;
			int y = x + i;
			
			x *= y;
		}
		
		// Create the main application frame.
		XAppFrame frame = new XAppFrame(app);
		
		app.getActiveAppFrame().getStatusBar().addProgressBar();
		
		ABOUT_ACTION = new AbstractAction() {
			public void actionPerformed(ActionEvent event) {
				XAboutBox aboutBox = new XAboutBox();
				
				aboutBox.setImage(XApp.getApp().getResources().getIcon("/eclipse/org.eclipse.ui/icons/full/wizban/new_wiz.gif"));
				aboutBox.setText("<html><b>XFCSwingSet</b><br><br>A demonstration of the XFC framework.</html>");
				
				aboutBox.setVisible(true);
			}
		};
		
		app.registerGlobalAction("file-exit-action", app.getApplicationExitAction());
		app.registerGlobalAction("help-about-action", ABOUT_ACTION);
		
		JPanel contentPanel = frame.getFrameContent();
		
		JTabbedPane tabbedPane = new JTabbedPane();
		
		ExampleTab[] tabs = new ExampleTab[] {
			app.createActionLabelTab(),
			app.createBinderyTab(),
			app.createThrobberTab(),
			app.createErrorDialogTab(),
			app.createHelpBrowserTab(),
			app.createLoginDialogTab(),
			app.createMinimizablePanelTab(),
			app.createPreferenceDialogTab(),
			app.createPrintUtilitiesTab(),
			app.createProgressDialogTab(),
			app.createSplitPaneTab(),
			app.createTabbedPaneTab(),
			app.createTableTab(),
			app.createWizardDialogTab(),
		};
		
		Arrays.sort(tabs, new Comparator() {
			public int compare(Object arg1, Object arg2) {
				ExampleTab tab1 = (ExampleTab)arg1;
				ExampleTab tab2 = (ExampleTab)arg2;
				
				return tab1.getTitle().compareTo(tab2.getTitle());
			}
		});
		
		for (int i = 0; i < tabs.length; i++)
			tabbedPane.addTab(tabs[i].getTitle(), tabs[i]);
		
		contentPanel.setLayout(new BorderLayout());
		contentPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		contentPanel.add(tabbedPane, BorderLayout.CENTER);
		
		splashScreen.waitUntilShownFor(750);
		splashScreen.hide();
		
		frame.setTitle("XFCSwingSet");
		frame.setSize(600, 400);
		frame.setVisible(true);
	}
	
	public XFCSwingSet()
	{
		super("XFC SwingSet");
	}
	
	private ExampleTab createActionLabelTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"pref:grow",
			"pref 10dlu pref 10dlu pref:grow"
		));
		
		XActionLabel label1 = new XActionLabel("Click for freedom!");
		label1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				ABOUT_ACTION.actionPerformed(event);
			}
		});
		
		XActionLabel label2 = new XActionLabel("This is a disabled link");
		label2.setEnabled(false);
		label2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				ABOUT_ACTION.actionPerformed(event);
			}
		});
		
		XActionLabel label3 = new XActionLabel("A link with an icon");
		label3.setIcon(getResources().getIcon("/eclipse/org.eclipse.ui/icons/full/eview16/bkmrk_nav.gif"));
		label3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				ABOUT_ACTION.actionPerformed(event);
			}
		});
		
		panel.add(label1, "1, 1, l, c");
		panel.add(label2, "1, 3, f, f");
		panel.add(label3, "1, 5, f, t");
		
		String description = "XActionLabels act just like hyperlink labels in a browser.";
		
		return new ExampleTab("XActionLabel", description, panel);
	}
	
	private ExampleTab createMinimizablePanelTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"pref:grow 10dlu pref:grow",
			"pref 0px pref:grow"
		));
		
		XMinimizablePanel panel1 = new XMinimizablePanel("Panel one");
		panel1.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
		panel1.add(new JButton("Hello world!"));
		
		XMinimizablePanel panel2 = new XMinimizablePanel("Panel two");
		panel2.setBorder(BorderFactory.createLineBorder(Color.GRAY));
		panel2.add(new JButton("Hello world!"));
		
		XMinimizablePanel panel3 = new XMinimizablePanel("Panel three");
		panel3.setLayout(new BorderLayout());
		XMultilineLabel label = new XMultilineLabel(XUtils.getLoremIpsumText(500).replace('\n', ' '));
		label.setPreferredWidth(400);
		panel3.add(label, BorderLayout.NORTH);
		
		panel.add(panel1, "1, 1, f, f");
		panel.add(panel2, "1, 3, f, f");
		panel.add(panel3, "3, 1, 1, 3, f, f");
		
		String description = "XMinimizablePanels allow you to embed content in user minimizable panels.";
		
		return new ExampleTab("XMinimizablePanel", description, panel);
	}
	
	private ExampleTab createThrobberTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"10dlu:grow pref 20dlu:grow pref 25dlu pref 10dlu:grow",
			"pref:grow"
		));
		
		final XThrobber throbber1 = new XThrobber();
		final XThrobber throbber2 = new XThrobber(true);
		
		final JButton button = new JButton("Start");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				if (throbber1.isRunning())
				{
					throbber1.stopThrobber();
					throbber2.stopThrobber();
					button.setText("Start");
				}
				else
				{
					throbber1.startThrobber();
					throbber2.startThrobber();
					button.setText("Stop");
				}
			}
		});
		
		panel.add(button, 		"2, 1, c, c");
		panel.add(throbber1, 	"4, 1, c, c");
		panel.add(throbber2, 	"6, 1, c, c");
		
		return new ExampleTab(
			"XThrobber",
			"The XThrobber component is used to display indeterminate progress.",
			panel
		);
	}
	
	private ExampleTab createBinderyTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"30dlu pref",
			"pref 10dlu pref"
		));
		
		XCompositeEditor addressEditor = new XCompositeEditor();
		final Address address = new Address();
		
		XStringEditor nameEditor = new XStringEditor("Name");
		XStringEditor streetEditor = new XStringEditor("Street");
		XStringEditor cityEditor = new XStringEditor("City");
		XStringEditor stateEditor = new XStringEditor("State", 2);
		XStringEditor zipEditor = new XStringEditor("ZIP", 5);
		
		final JLabel label = new JLabel();
		
		XBindery.bind(address, "name", nameEditor);
		XBindery.bind(address, "street", streetEditor);
		XBindery.bind(address, "city", cityEditor);
		XBindery.bind(address, "state", stateEditor);
		XBindery.bind(address, "zip", zipEditor);
		
		address.addPropertyChangeListener(new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent event) {
				label.setText(address.toString());
			}
		});
		
		addressEditor.addEditor(nameEditor);
		addressEditor.addEditor(streetEditor);
		addressEditor.addEditor(cityEditor);
		addressEditor.addEditor(stateEditor);
		addressEditor.addEditor(zipEditor);
		
		panel.add(addressEditor, 	"2, 1");
		panel.add(label,			"2, 3");
		
		return new ExampleTab(
			"XBindery",
			"The XBindery class is used to bind an object's property to an XEditor component.",
			panel
		);
	}
	
	static class Address
		extends XObject
	{
		public String getName()
		{
			return (String)getValue("name");
		}

		public void setName(String name)
		{
			setValue("name", name);
		}

		public String getState()
		{
			return (String)getValue("state");
		}

		public void setState(String state)
		{
			setValue("state", state);
		}

		public String getStreet()
		{
			return (String)getValue("street");
		}

		public void setStreet(String street)
		{
			setValue("street", street);
		}

		public String getZip()
		{
			return (String)getValue("zip");
		}

		public void setZip(String zip)
		{
			setValue("zip", zip);
		}

		public String getCity()
		{
			return (String)getValue("city");
		}
		
		public void setCity(String city)
		{
			setValue("city", city);
		}
		
		public String toString()
		{
			return getName() + ", " + getStreet() + ", " + getCity() + ", " + getState() + " " + getZip();
		}
	}
	
	private ExampleTab createTabbedPaneTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"pref 6px pref:grow",
			"pref 3dlu pref 3dlu pref:grow"
		));
		
		XResources resources = XApp.getApp().getResources();
		
		final XTabbedPane tabbedPane = new XTabbedPane();
		
		final JLabel currentTabLabel = new JLabel();
		
		tabbedPane.addTabbedPaneListener(new XTabbedPaneListenerAdapter() {
			public void tabDeselected(XTabbedPaneTab tab) {
				currentTabLabel.setText("");
			}
			public void tabSelected(XTabbedPaneTab tab) {
				currentTabLabel.setText(tab.getTitle());
			}
			public void tabAdded(XTabbedPaneTab tab) {
				tabbedPane.getTabAt(0).setTitle("Test Tab One: " + tabbedPane.getTabCount());
			}
			public void tabRemoved(XTabbedPaneTab tab) {
				tabbedPane.getTabAt(0).setTitle("Test Tab One: " + tabbedPane.getTabCount());
			}
		});
		
		JButton button = new JButton("Create New Tab");
		
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				XTabbedPaneTab tab = new XTabbedPaneTab("Tab " + (System.currentTimeMillis() % 1000));
				
				tab.setCloseableTab(true);
				tab.setToolTipText("sample tooltip text: " + tab.getTitle());
				tab.setComponent(new XMultilineLabel(XUtils.getLoremIpsumText(400)));
				
				tabbedPane.addTab(tab);
			}
		});
		
		Icon icon1 = resources.getIcon("/firefox/skin/classic/mozapps/update/update.png");
		Icon icon2 = resources.getIcon("/firefox/skin/classic/global/icons/wrap.png");
		
		tabbedPane.addTab(new XTabbedPaneTab("Test Tab One", icon1, createCenteredPanel(new JButton("test test one"))));
		XTabbedPaneTab tab = new XTabbedPaneTab("Test Tab Two", icon1, createCenteredPanel(new JButton("test test two")));
		tab.setCloseableTab(true);
		tabbedPane.addTab(tab);
		tab = new XTabbedPaneTab("Test Tab Three", icon2, createCenteredPanel(new JButton("test test three")));
		tabbedPane.addTab(tab);
		
		panel.add(new JLabel("Current tab:"), 	"1, 1, r, c");
		panel.add(currentTabLabel,				"3, 1, l, c");
		panel.add(button,						"1, 3, c, c");
		panel.add(tabbedPane, 					"1, 5, 3, 1, f, f");
		
		return new ExampleTab(
			"XTabbedPane",
			"TODO:",
			panel
		);
	}
	
	private JPanel createCenteredPanel(JComponent component)
	{
		JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
		
		panel.setBorder(BorderFactory.createEmptyBorder(50, 0, 0, 0));
		panel.add(component);
		
		return panel;
	}
	
	private ExampleTab createTableTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"pref:grow",
			"pref:grow"
		));
		
		XTable table = new XTable();
		
		// Draw the table rows w/ a row number.
		table.getRowHeader().setDefaultRenderer(new XRowHeaderRenderer(true));
		
		table.addColumn(new XTableColumn("Key Name", String.class, 250) {
			public Object getValue(Object rowObject) {
				return rowObject;
			}
		});
		table.addColumn(new XTableColumn("Rendering", Object.class, 90) {
			{ setCellRenderer(new FlexibleRenderer()); }
			public Object getValue(Object rowObject) {
				Icon icon = UIManager.getIcon(rowObject);
				
				if (icon != null)
					return icon;
				
				Color color = UIManager.getColor(rowObject);
				
				if (color != null)
					return color;
				
				Font font = UIManager.getFont(rowObject);
				
				if (font != null)
					return font;
				
				return null;
			}
		});
		table.addColumn(new XTableColumn("UIManager Value", String.class, 375) {
			public Object getValue(Object rowObject) {
				Object result = UIManager.get(rowObject);
				
				if (result instanceof String)
					return result;
				
				return result == null ? null : result.toString();
			}
		});
		
		EventList list = new BasicEventList();
		
		for (Enumeration e = UIManager.getDefaults().keys(); e.hasMoreElements(); )
		{
			Object object = e.nextElement();
			
			if (object instanceof String)
				list.add(object);
		}
		
		table.setRowObjects(list);
		
		panel.add(table, "1, 1, f, f");
		
		return new ExampleTab(
			"XTable",
			"TODO:",
			panel
		);
	}
	
	/**
	 * For use by the XTable example.
	 */
	private static class FlexibleRenderer
		extends DefaultTableCellRenderer
	{
		Color 	defaultBackground;
		Border	loweredBorder;
		Font	defaultFont;
		
		public FlexibleRenderer()
		{
			defaultBackground = getBackground();
			defaultFont = getFont();
			
			setHorizontalAlignment(JLabel.RIGHT);
	
			Color controlLight = UIManager.getColor("controlLtHighlight");
			Color controlDark = UIManager.getColor("controlDkShadow");
	
			loweredBorder = BorderFactory.createBevelBorder(BevelBorder.LOWERED, controlLight, controlDark);
		}
		
		public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean focused, int row, int column)
		{
			setIcon(null);
			setText(null);
			setBackground(defaultBackground);
			setBorder(null);
			setFont(defaultFont);
			
			super.getTableCellRendererComponent(table, "", selected, focused, row, column);
			
			if (value instanceof Icon)
			{
				setIcon((Icon)value);
			}
			else if (value instanceof Color)
			{
				setBackground((Color)value);
				setBorder(loweredBorder);
			}
			else if (value instanceof Font)
			{
				setText("Ran run dog");
				setFont((Font)value);
			}
			
			return this;
		}
	
		public void paint(Graphics g)
		{
			try
			{
				super.paint(g);
			}
			catch (ClassCastException cce)
			{
				// Some of the icons expect to be in a certain componet heirarchy when they're rendered.
			}
		}
	}
	
	private ExampleTab createHelpBrowserTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"pref:grow",
			"25px pref pref:grow"
		));
		
		JButton button1 = new JButton("Show Help Browser");
		button1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				
				XHelpBrowser helpBrowser = new XHelpBrowser();
				
				try
				{
					helpBrowser.addJavaHelpLibrary(new File("demos/org/xfc/xdemos/swingset/animals.jar")); // bad - needed editing - no fix
					helpBrowser.addJavaHelpLibrary(new File("demos/org/xfc/xdemos/swingset/invertebrates.jar"));
					
					//helpBrowser.addJavaHelpLibrary(new File("demos/org/xfc/xdemos/swingset/object.jar"));
					//helpBrowser.addEclipseLibrary(new File("src/org/xfc/help/org.eclipse.cdt.doc.isv_3.1.0.200606261600.jar"));
					//helpBrowser.addEclipseLibrary(new File("src/org/xfc/help/org.eclipse.pde.doc.user_3.2.0.v20060605.jar"));
					//helpBrowser.addJavaHelpLibrary(new File("demos/org/xfc/xdemos/swingset/vertebrates.jar"));
					//helpBrowser.addJavaHelpLibrary(new File("demos/org/xfc/xdemos/swingset/apidoc.jar")); // no toc - no fix
					//helpBrowser.addJavaHelpLibrary(new File("demos/org/xfc/xdemos/swingset/holidays.jar"));
					//helpBrowser.addJavaHelpLibrary(new File("demos/org/xfc/xdemos/swingset/idehelp.jar"));
				}
				catch (IOException ioe)
				{
					XErrorDialog.showError("Error Reading Help File", ioe);
				}
				
				helpBrowser.show();
			}
		});
		
		JPanel temp = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
		
		temp.add(button1);
		
		panel.add(temp, "1, 2, l, c");
		
		return new ExampleTab(
			"XHelpBrowser",
			"The help browser is a simple help window. It can handle JavaHelp and Eclipse format help files, and features out of the box searching capabilities.",
			panel
		);
	}
	
	private ExampleTab createLoginDialogTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"pref:grow",
			"25px pref pref:grow"
		));
		
		JButton button1 = new JButton("Show Login Dialog");
		button1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				XLoginDialog dialog = new XLoginDialog();
				
				dialog.setLoginImage(XApp.getApp().getResources().getIcon("/misc/login.png"));
				dialog.setLoginText(XUtils.getLoremIpsumText(120));
				
				boolean authenticated = dialog.authenticate(new XLoginDialog.Authenticator() {
					public boolean authenticate(String username, String password) {
						
						try { Thread.sleep(2000); } catch (InterruptedException ie) { }
						
						return "test".equals(username);
					}
				});
				
				if (!authenticated)
					System.out.println("Error authenticating: " + dialog.getUsername());
			}
		});
		
		JPanel temp = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
		
		temp.add(button1);
		
		panel.add(temp, "1, 2, l, c");
		
		return new ExampleTab(
			"XLoginDialog",
			"TODO:",
			panel
		);
	}
	
	private ExampleTab createErrorDialogTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"pref:grow",
			"25px pref 10dlu pref 10dlu pref pref:grow"
		));
		
		JButton button1 = new JButton("Error Dialog 1");
		button1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				XErrorDialog.showError("Error Title", "Error message.");
			}
		});
		
		JButton button2 = new JButton("Error Dialog 2");
		button2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				XErrorDialog dialog = new XErrorDialog("Error Title", "An error with a sub-message.");
				
				dialog.setSubMessage("Sub-message: " + XUtils.getLoremIpsumText());
				
				dialog.show();
			}
		});
		
		JButton button3 = new JButton("Error Dialog 3");
		button3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				XErrorDialog.showError("Unhandled Exception", new IOException("Unable to read file."));
			}
		});
		
		JButton button4 = new JButton("Warning Dialog");
		button4.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				XErrorDialog.showWarning("Warning Dialog", "This is a warning.");
			}
		});
		
		JButton button5 = new JButton("Information Dialog");
		button5.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				XErrorDialog.showInfo("Information Dialog", "System Properties", getSystemProperties());
			}
		});
		
		JPanel temp = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
		
		temp.add(button1);
		temp.add(Box.createHorizontalStrut(5));
		temp.add(button2);
		temp.add(Box.createHorizontalStrut(5));
		temp.add(button3);
		
		panel.add(temp, "1, 2, l, c");
		panel.add(button4, "1, 4, l, c");
		panel.add(button5, "1, 6, l, c");
		
		String description = "The XErrorDialog class handles displaying error, warning, and information dialogs. Error dialogs can have titles, messages, and sub-messages. Error dialogs can also handle displaying exceptions.";
		
		return new ExampleTab("XErrorDialog", description, panel);
	}
	
	private static String getSystemProperties()
	{
		String str = "";
		int count = 0;
		
		for (Enumeration e = System.getProperties().keys(); e.hasMoreElements(); )
		{
			String key = (String)e.nextElement();
			
			str += key + "= " + System.getProperty(key) + "\n";
			
			if (++count == 7)
				return str.trim();
		}
		
		return str.trim();
	}
	
	private ExampleTab createProgressDialogTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"pref:grow",
			"25px pref pref:grow"
		));
		
		JButton button1 = new JButton("Sample Progress Dialog");
		button1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				final XProgressDialog dialog = new XProgressDialog();
				
				dialog.setText("Sample Progress Dialog");
				dialog.setDescription(XUtils.getLoremIpsumText(100));
				dialog.getProgressBar().setIndeterminate(true);
				dialog.setCancelListener(new ActionListener() {
					public void actionPerformed(ActionEvent event) {
						dialog.hide();
					}
				});
				
				new Thread() {
					public void run() {
						try { Thread.sleep(3000); } catch (InterruptedException ie) { }
						dialog.hide();
					}
				}.start();
				
				dialog.show();
			}
		});
		
		JPanel temp = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
		
		temp.add(button1);
		
		panel.add(temp, "1, 2, l, c");
		
		return new ExampleTab(
			"XProgressDialog",
			"A progress dialog.",
			panel
		);
	}
	
	private ExampleTab createPreferenceDialogTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"pref:grow",
			"25px pref pref:grow"
		));
		
		final XPreferenceDialog preferencesDialog = new XPreferenceDialog(XApp.getApp());
		
		JButton button1 = new JButton("Show Preference Dialog");
		button1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				preferencesDialog.show();
			}
		});
		
		panel.add(button1, "1, 2, l, c");
		
		XPreferenceTab tab1 = new XPreferenceTab("General") {
			public void loadSettings(double preferencesVersion, Preferences preferences) {
				
			}
			public void saveSettings(Preferences preferences) {
				
			}
		};
		tab1.setIcon(XApp.getApp().getResources().getIcon("/firefox/skin/classic/mozapps/update/update.png"));
		tab1.setComponentContents(new JButton("Hello world"));
		preferencesDialog.addPreferenceTab(tab1);
		
		XPreferenceTab tab2 = new XPreferenceTab("Connections") {
			public void loadSettings(double preferencesVersion, Preferences preferences) {
				
			}
			public void saveSettings(Preferences preferences) {
				
			}
		};
		tab2.setIcon(XApp.getApp().getResources().getIcon("/firefox/skin/classic/global/icons/wrap.png"));
		XStringEditor prefEditor2 = new XStringEditor("URL");
		prefEditor2.setValue("Two two two");
		tab2.setEditorContents(prefEditor2);
		preferencesDialog.addPreferenceTab(tab2);
		
		XPreferenceTab tab3 = new XPreferenceTab("Security") {
			public void loadSettings(double preferencesVersion, Preferences preferences) {
				
			}
			public void saveSettings(Preferences preferences) {
				
			}
		};
		tab3.setIcon(XApp.getApp().getResources().getIcon("/firefox/skin/classic/global/icons/notfound.png"));
		XStringEditor prefEditor3 = new XStringEditor("URL");
		prefEditor3.setEnabled(false);
		tab3.setEditorContents(prefEditor3);
		preferencesDialog.addPreferenceTab(tab3);
		
		return new ExampleTab(
			"XPreferenceDialog",
			"TODO:",
			panel
		);
	}
	
	private ExampleTab createPrintUtilitiesTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"pref:grow",
			"25px pref pref:grow"
		));
		
		JButton button1 = new JButton("Printing Test");
		button1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				XPrintUtilities.print(new MockPrintable(), "XFCSwingSet Print Test");
			}
		});
		
		JButton button2 = new JButton("Print Preview Dialog");
		button2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				XPrintUtilities.printPreview(new MockPrintable(), "XFCSwingSet Print Test");
			}
		});
		
		JPanel temp = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
		
		temp.add(button1);
		temp.add(Box.createHorizontalStrut(5));
		temp.add(button2);
		
		panel.add(temp, "1, 2, l, c");
		
		return new ExampleTab(
			"XPrintUtilities",
			"XFC supports both a standard print preview dialog, as well as offering utility classes and methods to made printing easier.",
			panel
		);
	}
	
	private ExampleTab createWizardDialogTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"pref:grow",
			"25px pref pref:grow"
		));
		
		JButton button1 = new JButton("Sample Wizard");
		button1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				XWizardDialog wizard = new XWizardDialog();
				
				wizard.setTitle("Sample Wizard");
				
				final JCheckBox pageInvalid = new JCheckBox("Mark page invalid");
				
				XDefaultWizardPage page1 = new XDefaultWizardPage();
				page1.setTitle("Sample wizard page 1");
				page1.setDescription(XUtils.getLoremIpsumText(50));
				page1.add(new JButton("Hello world"));
				
				final XDefaultWizardPage page2 = new XDefaultWizardPage();
				page2.setTitle("Sample wizard page 2");
				page2.add(pageInvalid);
				pageInvalid.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent event) {
						if (pageInvalid.isSelected())
						{
							page2.setValidationError(true);
							page2.setValidationMessage("You must de-select the check box to continue.");
						}
						else
						{
							page2.setValidationError(false);
							page2.setValidationMessage(null);
						}
					}
				});
				
				XDefaultWizardPage page3 = new XDefaultWizardPage();
				page3.setTitle("Sample wizard page 3 (final page)");
				page3.setDescription(XUtils.getLoremIpsumText(200));
				page3.add(new JLabel("<html><i>- fini -</i></html>"));
				
				page1.setNextPage(page2);
				page2.setNextPage(page3);
				
				wizard.addWizardPage(page1);
				wizard.addWizardPage(page2);
				wizard.addWizardPage(page3);
				
				wizard.setWizardListener(new XWizardListenerAdapter() {
					public void wizardFinished(XWizardDialog wizard) {
						XErrorDialog.showInfo("Sample Wizard Completed!", XUtils.getLoremIpsumText());
					}
				});
				
				wizard.show();
			}
		});
		
		JButton button2 = new JButton("Sample Wizard 2");
		button2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				
			}
		});
		
		JPanel temp = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
		
		temp.add(button1);
		//temp.add(Box.createHorizontalStrut(5));
		//temp.add(button2);
		
		panel.add(temp, "1, 2, l, c");
		
		return new ExampleTab(
			"XWizardDialog",
			"TODO:",
			panel
		);
	}
	
	private ExampleTab createSplitPaneTab()
	{
		JPanel panel = new JPanel(new FormLayout(
			"pref:grow",
			"pref:grow"
		));
		
		final JButton splitButton = new JButton("Split me");
		
		XSplitPane splitPane3 = new XSplitPane(XSplitPane.HORIZONTAL, splitButton, new JLabel("Label", JLabel.CENTER));
		XSplitPane splitPane1 = new XSplitPane(XSplitPane.HORIZONTAL);
		XSplitPane splitPane2 = new XSplitPane(XSplitPane.VERTICAL, splitPane3, new JButton("Hello World!"));
		
		splitPane1.setLeftComponent(new JScrollPane(new JTextArea("sdfjksdfkj kjdsfhk\nsdfsdfsd\nsfdsdf")));
		splitPane1.setRightComponent(splitPane2);
		
		splitPane1.createDefaultBorder();
		
		// Demonstrate the ability to split cells into new XSplitPanes.
		splitButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				XSplitPane splitPane = (XSplitPane)splitButton.getParent();
				
				int orientation = (splitPane.getOrientation() == XSplitPane.VERTICAL ? XSplitPane.HORIZONTAL : XSplitPane.VERTICAL);
				
				JLabel label = new JLabel("Abc");
				label.setBorder(BorderFactory.createEtchedBorder());
				
				splitPane.splitLeftComponent(orientation, label);
			}
		});
		
		panel.add(splitPane1, "1, 1, f, f");
		
		return new ExampleTab(
			"XSplitPane",
			"TODO:",
			panel
		);
	}
	
	private static class MockPrintable
		implements Printable
	{
		public int print(Graphics g, PageFormat pageFormat, int page)
			throws PrinterException
		{
			if (page >= 8)
				return Printable.NO_SUCH_PAGE;
			
			Rectangle 	bounds = g.getClipBounds();
			int 		minWidth = Math.min(bounds.width, bounds.height);
			
			int yOffset = g.getFontMetrics().getHeight() * page;
			
			g.drawString(XUtils.getLoremIpsumText(75), bounds.x + 36, bounds.y + 72 + yOffset);
			g.drawString("Page " + (page + 1), bounds.x + 36, bounds.y + bounds.height - 36);
			g.drawLine(bounds.x, bounds.y + bounds.height / 2, bounds.x + bounds.width, bounds.y + bounds.height / 2);
			g.drawLine(bounds.x, bounds.y, bounds.x + minWidth, bounds.y + minWidth);
			g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
			
			//try { Thread.sleep(350); } catch (InterruptedException ie) { }
			
			return Printable.PAGE_EXISTS;
		}
	}
	
	private static class ExampleTab
		extends JPanel
	{
		private String title;
		
		ExampleTab(String title, String description, JComponent contents)
		{
			this.title = title;
			
			XMultilineLabel descriptionLabel = new XMultilineLabel();
			descriptionLabel.setPreferredWidth(500);
			descriptionLabel.setText(description);
			
			setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
			setLayout(new FormLayout(
				"pref:grow",
				"pref 10dlu pref:grow"
			));
			
			add(descriptionLabel, 	"1, 1, f, c");
			add(contents, 			"1, 3, f, f");
		}
		
		public String getTitle()
		{
			return title;
		}
	}
	
}
